import os
import tempfile, os, shutil

from model.ssh_connector import SSHConnector
from model.common import Common
from model.config_reader import ConfigReader
from core import bus


class UploadPresenter():
    """软件包上传/部署"""

    def __init__(self, view, server_manager):
        super().__init__()
        self.view = view
        self.server_manager = server_manager
        self.common = Common()
        self.ssh = SSHConnector()
        self.config_reader = ConfigReader()

        self.remote_base_dir = self.config_reader.get_value('remote', 'base_dir', '/root/')
        self.expected_md5 = self.config_reader.get_value('remote', 'md5_value', '')
        self.extract_command = self.config_reader.get_value("remote", "extract_command", "")

    def _ready_connect(self):
        servers = self.server_manager.get_connected_servers()
        if not servers:
            bus.log_message.emit("请先测试连接")
            return []
        return servers

    def handle_combo(self):
        return self.server_manager.get_all_servers()

    # -------------------- 上传 --------------------
    def handle_upload(self, file_path):
        servers = self._ready_connect()
        if not servers: return

        if not os.path.exists(file_path):
            return bus.log_message.emit(f"{file_path} 不存在")      
        
        file_name = os.path.basename(file_path)

        def do_upload(server):
            remote_path = os.path.join(self.remote_base_dir, file_name)
            return self.ssh.upload_file(server, file_path, remote_path)
        def on_finished(results):
            bus.dialog_message.emit(results)

        self.common.run_task(do_upload, servers, on_finished)

    # -------------------- 校验 MD5 --------------------
    def handle_verify(self, file_path, local_md5_value):
        servers = self._ready_connect()
        if not servers: return
        
        file_name = os.path.basename(file_path)
        if not file_name:
            bus.log_message.emit(f"请选择文件")
            return

        def do_verify(server):
            remote_path = os.path.join(self.remote_base_dir, file_name)
            result = self.ssh.execute_command(server, f"md5sum {remote_path}")
            remote_md5_value = result.get("stdout", "").strip().split()[0]

            if remote_md5_value.lower() != local_md5_value.lower():
                result['msg'] = f"{remote_path} md5({remote_md5_value}) != local md5({local_md5_value})"
            return result
        def on_finished(results):
            bus.dialog_message.emit(results)

        self.common.run_task(do_verify, servers, on_finished)

    # -------------------- 执行命令 --------------------
    def handle_execute(self, command):
        servers = self._ready_connect()
        if not servers: return

        def do_exec(server):
            return self.ssh.execute_command(server, command)
        
        def on_finished(results):
            bus.dialog_message.emit(results)

        self.common.run_task(do_exec, servers, on_finished)

    # -------------------- 一键部署 --------------------
    def handle_deploy(self, file_path):
        servers = self._ready_connect()
        if not servers: return
        
        if not self.expected_md5:
            bus.error_message.emit("未在配置文件中找到 MD5 值")
            return

        remote_path = os.path.join(self.remote_base_dir, os.path.basename(file_path))

        extract_cmd = self.extract_command.format(file=remote_path, base_dir=self.remote_base_dir) \
            if self.extract_command else ""

        def do_deploy(server):
            # 上传
            result = self.ssh.upload_file(server, file_path, remote_path)
            if not result.get('status'):
                return result

            # 校验 MD5
            result = self.ssh.execute_command(server, f"md5sum {remote_path}")
            remote_md5_value = result.get("stdout", "").strip().split()[0]

            if remote_md5_value.lower() != self.expected_md5.lower():
                result['msg'] = f"{remote_path} md5({remote_md5_value}) != local md5({self.expected_md5})"
                return result

            # 解压命令 
            return self.ssh.execute_command(server, extract_cmd)

        def on_finished(results):
            bus.dialog_message.emit(results)

        self.common.run_task(do_deploy, servers, on_finished)

    # -------------------- 分发 --------------------
    def handle_distribute(self, src_server, src_path, dst_path):
        """从源服务器复制文件到多个目标"""
        servers = self._ready_connect()
        if not servers: return

        tmp_dir = tempfile.mkdtemp(prefix="transfer_")
        local_dir = tmp_dir 

        result = self.ssh.download_with_tar(src_server, src_path, local_dir)
        if not result.get("status") or not os.path.exists(result.get("msg", "")):
            bus.dialog_message.emit(result)
            return

        def worker(dst):
            return self.ssh.upload_tar_and_extract(dst, result['msg'], dst_path)
        
        def on_finished(results):
            if os.path.exists(tmp_dir):
                shutil.rmtree(tmp_dir, ignore_errors=True)
            bus.dialog_message.emit(results)

        self.common.run_task(worker, servers, on_finished)
